//
//  WBRefreshControl.swift
//  GitWeibo
//
//  Created by 胡金东 on 2017/6/13.
//  Copyright © 2017年 胡金东. All rights reserved.
//

import UIKit

/// - 刷新状态临界点
private let refreshOffset:CGFloat = 120
/// - 定义刷新枚举
///
/// - normal: 普通状态，什么都不做
/// - pulling: 超过临界点，如果方手，开始刷新
/// - willRefresh: 用户超过临界点，并且方手
enum RefreshStatus{
    case normal
    case pulling
    case willRefresh
}

/// - 刷新控件
class WBRefreshControl: UIControl {

  weak var scroll : UIScrollView?
    /// - 刷新View
    var refreshView : RefreshView = RefreshView.refreshView()
    
    //MARK: -  构造函数
    override init(frame: CGRect) {
        super.init(frame: CGRect())
        
        setUpUI()
    }
    /// - xib 会调用
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        setUpUI()
    }
    /// - 在addSubview 添加子控件时候会调用
    /// - 当添加到父视图时候，newSuperview是父视图
    /// - 当父视图被移除的时候，newSuperview为nil
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        /// - 判断父类的类型
        guard let sv = newSuperview as? UIScrollView else {
            return
        }
        /// - 记录父视图
        scroll = sv
        
        /// - KVO 监听父视图的contenoffset
        scroll?.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
    }
    /// - 移除KVO监听
    override func removeFromSuperview() {
        /// - superView 这个时候还在 ，所以要写在 super.removeFromSuperview()之前
        super.removeObserver(self, forKeyPath: "contentOffset")
        super.removeFromSuperview()
        
        /// - superView 这个时候已经不在了
    }
    
    /// - 所有 KVO 方法会统一调用此方法
    /// - 在程序中，通常只监听一个方法的几个属性，如果属性太多，方法很乱
    /// - 观察者模式在不需要的时候，都需要释放
    /// - 通知中心：如果不释放，什么也不会发生，但会内存泄漏，会有多次注册
    /// - KVO: 如果不释放，会崩溃
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        guard let sv = scroll  else {
            return
        }
        print("contetnInset==\(sv.contentInset.top) contentOffset==\(sv.contentOffset.y)")
        
        /// - 初始化高度就应该是0
        let height = -(sv.contentInset.top + sv.contentOffset.y)
        /// - 向上推，是不用调用的
        if height < 0 {
            return
        }
        /// - 可以根据高度设置刷新控件
        self.frame = CGRect(x: 0, y: -height, width: sv.bounds.width, height: height)
        /**
         传递父视图高度
         */
        refreshView.parentViewheight = height
        
        /// - 是否在下拉,只判断一次
        if sv.isDragging {
            if height > refreshOffset  && (refreshView.refreshStatus == .normal) {
                refreshView.refreshStatus = .pulling
                
            }else if height <= refreshOffset && (refreshView.refreshStatus == .pulling){
                refreshView.refreshStatus = .normal
                
            }
        }else{ /// - 放手
            /// - 放手时pulling 说明手拉已经超过临界点，状态改为刷新
            if refreshView.refreshStatus == .pulling {
                
                 beginRefreshing()
                /// - 发送刷新数据事件 调用
                sendActions(for: .valueChanged)
            }
        }
        
        
    }
    
    
    
    
    
    /// - 开始刷新
    func beginRefreshing()  {
        /// - 判断父视图 是父视图走下面，不是直接返回
        guard let sv = scroll else {
            return
        }
        /// - 判断如果正在刷新 就直接返回
        if refreshView.refreshStatus == .willRefresh {
            return
        }
        
        /// - 刷新结束之后，将状态修改为 .normal 才能够继续响应刷新
        refreshView.refreshStatus = .willRefresh
        /// - 显示刷新视图，调整刷新视图位置
        var inste = sv.contentInset
        inste.top += refreshOffset
        sv.contentInset = inste
        /// - 设置刷新视图的父视图高度（美图独有，其他的可以不设）
        refreshView.parentViewheight = refreshOffset

    }
    
    /// - 结束刷新
    func endRefreshing()  {
        
        guard let sv = scroll else {
            return
        }
        /// - 如果不是刷新状态，直接返回
        if refreshView.refreshStatus != .willRefresh {
            return
        }
        
        /// - 刷新结束 恢复正常
        refreshView.refreshStatus = .normal
        /// - 把多出位置，减回去，还原
        var insteted = sv.contentInset
        insteted.top -= refreshOffset
        sv.contentInset = insteted
        
        
    }
}


extension WBRefreshControl {
    
    func setUpUI()  {
        backgroundColor = superview?.backgroundColor
        /// - 设置超出边界的不显示
//        clipsToBounds = true
        /// - 添加刷新视图
        addSubview(refreshView)
        /// - 自动布局 - 设置xib 控件的自动布局，
        refreshView.translatesAutoresizingMaskIntoConstraints = false
        
        addConstraint(NSLayoutConstraint(item: refreshView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: refreshView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: refreshView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: refreshView.bounds.width))
        
        addConstraint(NSLayoutConstraint(item: refreshView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: refreshView.bounds.height))
    }
}
